import base64
import json
import os
import uuid
from jwt import decode as jwt_decode
from captcha.models import CaptchaStore
from captcha.views import captcha_image
from django.forms import model_to_dict
from django.http import JsonResponse
from rest_framework.views import APIView
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework_simplejwt.views import TokenObtainPairView

# 自定义登录认证返回的信息
from auth_app.models import User
from django_it_community import settings
from it_app.models import Follow, Collect, Message


class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
    def validate(self, attrs):
        data = super().validate(attrs)
        refresh = self.get_token(self.user)
        data['refresh'] = str(refresh)
        data['access'] = str(refresh.access_token)

        # Add extra responses here
        data['user_id'] = self.user.id
        data['role'] = self.user.is_superuser
        return data


class MyTokenObtainPairView(TokenObtainPairView):
    serializer_class = MyTokenObtainPairSerializer


class CaptchaApiView(APIView):
    # 获取验证码
    def get(self, request):
        hashkey = CaptchaStore.generate_key()  # 生成验证码记录，往验证码表中插入一条记录
        img = captcha_image(request, hashkey)  # 生成image response
        # 将二进制流转成base64
        encoded_image = base64.b64encode(img.content).decode('utf-8')
        response_data = {
            'captchaUrl': 'data:image/png;base64,' + encoded_image,  # 根据实际图片类型修改MIME类型
            'captchaKey': hashkey,
        }
        return JsonResponse({"code": 0, "msg": "", "data": response_data})

    # 校验验证码
    def post(self, request):
        rd = json.loads(request.body)
        cap = CaptchaStore.objects.filter(hashkey=rd['key']).first()
        if cap.response == rd['cap'].lower():
            return JsonResponse({"code": 0, "msg": "", "data": {}})
        return JsonResponse({"code": 9, "msg": "验证码错误", "data": {}})


# 注册
def register(request):
    try:
        rd = json.loads(request.body)
        if User.objects.filter(username=rd['username']).exists():
            return JsonResponse({"code": 9, "msg": "该账号已被注册", "data": {}})
        elif User.objects.filter(phone=rd['phone']).exists():
            return JsonResponse({"code": 9, "msg": "该手机号码已被注册", "data": {}})
        else:
            user = User.objects.create(
                username=rd['username'],
                first_name=rd['first_name'],
                phone=rd['phone'],
                email=rd['email'],
                sex=rd['sex'],
                is_superuser=rd['is_superuser'],
            )
            user.set_password(rd['password'])
            user.save()
            return JsonResponse({"code": 0, "msg": "注册成功", "data": {}})
    except Exception as e:
        return JsonResponse({"code": 9, "msg": str(e), "data": {}})


# 获取用户信息
def get_user_info(request):
    try:
        # 获取当前用户id
        user_id = jwt_decode(request.headers.get('Authorization').split(' ')[-1], settings.SECRET_KEY, algorithms=["HS256"])['user_id']
        user = User.objects.filter(id=user_id).first()
        return JsonResponse({"code": 0, "msg": "", "data": {
            **model_to_dict(user),
            "password": "",
            "notice_num": Follow.objects.filter(being_followed_id=user_id, is_read=0).count() +
                          Collect.objects.filter(article__user_id=user_id, is_read=0).count() +
                          Message.objects.filter(user_id=user_id, is_read=0).count()
        }})
    except Exception as e:
        print(e)
        return JsonResponse({"code": 9, "msg": str(e), "data": {}})


# 获取用户信息
def update_user_info(request):
    try:
        rd = json.loads(request.body)
        user = User.objects.filter(id=rd["id"])
        user.update(
            phone=rd['phone'],
            email=rd['email'],
            sex=rd['sex'],
            first_name=rd['first_name'],
        )
        if rd['password'] != "":
            user = User.objects.get(id=rd["id"])
            user.set_password(rd['password'])
            user.save()
        return JsonResponse({"code": 0, "msg": "修改成功", "data": {}})
    except Exception as e:
        return JsonResponse({"code": 9, "msg": str(e), "data": {}})


# 用户头像上传
def upload_ava(request):
    try:
        rd = request.POST
        file = request.FILES.get('file')
        # 获取文件格式
        filename = file.name.split('.')
        newfilename = str(uuid.uuid4()) + '.' + filename[-1]
        with open('static/source/%s' % newfilename, 'wb+') as destination:
            for chunk in file.chunks():
                destination.write(chunk)
        user = User.objects.filter(id=rd.get('user_id'))
        if user.first().ava:
            os.remove('static/source/%s' % user.first().ava)
        user.update(
            ava=newfilename
        )
        return JsonResponse({"code": 0, "msg": "设置成功", "data": {}})
    except Exception as e:
        print(e)
        return JsonResponse({"code": 9, "msg": str(e), "data": {}})


def forgot(request):
    try:
        rd = json.loads(request.body)
        user = User.objects.filter(username=rd.get('username'), phone=rd.get('phone'))
        if user.exists():
            use = User.objects.get(username=rd.get('username'), phone=rd.get('phone'))
            use.set_password(rd.get('password'))
            use.save()
            return JsonResponse({"code": 0, "msg": "重置成功", "data": {}})
        else:
            return JsonResponse({"code": 9, "msg": "账号和手机号码不匹配", "data": {}})
    except Exception as e:
        print(e)
        return JsonResponse({"code": 9, "msg": str(e), "data": {}})
